#include <os/ipc.h>


#define NUM_MAX_MBOX 16
mbox_t mbox_table[NUM_MAX_MBOX]={
	{.name = NULL,
		.status = NOTUSING,
		.nbytes = 0,
		.refer_num = 0,
		.send_queue = 0,
		.recv_queue = 0}
};
int do_mbox_open(char *name){
	int i;
	for(i=0;i<NUM_MAX_MBOX;i++)
		if(mbox_table[i].status == USING && kstrcmp(name,mbox_table[i].name)==0)
			break;
	if(i==NUM_MAX_MBOX){
        for(i=0;i<NUM_MAX_MBOX;i++)
            if(mbox_table[i].status==NOTUSING)
                break;
    }
    mbox_table[i].name = name;
    mbox_table[i].status = USING;
    mbox_table[i].refer_num++;
    return i;
}
void do_mbox_close(int mbox_id){
	int i;
	if(mbox_table[mbox_id].status != USING)
		return;
	mbox_t *mailbox = &mbox_table[mbox_id];
	mailbox->refer_num--;
    if(mailbox->refer_num==0){
        //if(!queue_is_empty(&(mailbox->sending_queue)))  prints("close: wrong refer num!\n");
        //if(!queue_is_empty(&(mailbox->recving_queue)))  prints("close: wrong refer num!\n");
        mailbox->nbytes=0;
    	mailbox->name=NULL;
    	mailbox->refer_num=0;
    	mailbox->status=NOTUSING;
    	queue_init(&(mailbox->send_queue));
    	queue_init(&(mailbox->recv_queue));
    }
}
void do_mbox_send(int mbox_id, void *msg, int msg_length){
    mbox_t *mailbox = &mbox_table[mbox_id];
	while(mailbox->nbytes!=0){
        do_block(&(mailbox->send_queue));
    }
    kmemcpy(mailbox->buff,msg,msg_length);
    mailbox->nbytes=msg_length;
    do_unblock(&(mailbox->recv_queue));
}
void do_mbox_recv(int mbox_id, void *msg, int msg_length){
    mbox_t *mailbox = &mbox_table[mbox_id];
	while(mailbox->nbytes==0){
        do_block(&(mailbox->recv_queue));
    }
    kmemcpy(msg,mailbox->buff,msg_length);
    mailbox->nbytes=0;
    do_unblock(&(mailbox->send_queue));
}